# -*- coding: utf-8 -*-
"""
---------------------------------------
@File    ：ip_get.py
@Author  ：liyunhui
@Date    ：2024/9/17 上午10:16 
@explain : 文件说明
---------------------------------------
"""
import json
import tornado
import time
from config import config
from methods.custom_log import create_logging
from methods.redis_connect import get_redis_cli
from tornado_swagger.model import register_swagger_model


@register_swagger_model
class IpGetModel:
    """
    IP获取模型，用于描述返回的IP数据
    ---
    type: object
    properties:
      status:
        type: string
        description: 请求的状态 (success 或 error)
      ip:
        type: string
        description: 获取到的代理IP地址
    """
    pass


class IpGetHandler(tornado.web.RequestHandler):

    def __init__(self, *args, **kwargs):
        super(IpGetHandler, self).__init__(*args, **kwargs)
        self.logging = create_logging("ip_get")
        self.total_calssify_key = config.total_classify_proxy
        self.redis_cli = get_redis_cli()

    def get(self):
        """
        获取指定分类的代理IP, GET 接收参数 classify_name
        ---
        tags:
        - IP 获取
        summary: 根据分类名称获取代理IP
        produces:
            - application/json
        parameters:
          - name: classify_name
            in: query
            description: 代理IP的分类名称
            required: true
            type: string
        responses:
          200:
            description: 成功获取代理IP
            schema:
              type: object
              properties:
                status:
                  type: string
                  example: success
                ip:
                  type: string
                  description: 返回的代理IP地址
          400:
            description: 请求参数错误
            schema:
              type: object
              properties:
                status:
                  type: string
                  example: error
                message:
                  type: string
          404:
            description: 分类代理池不存在
            schema:
              type: object
              properties:
                status:
                  type: string
                  example: error
                message:
                  type: string
          500:
            description: 获取代理IP失败
            schema:
              type: object
              properties:
                status:
                  type: string
                  example: error
                message:
                  type: string
        """
        classify_name = self.get_argument("classify_name", None)
        if not classify_name:
            self.logging.error("缺少分类代理参数：classify_name (分类名称)")
            self.set_status(400)
            self.write(json.dumps({'status': 'error', 'message': 'classify_name 参数缺失'}))
            return

        # 1, 组合该分类的IP代理key（如果存在则是list类型）
        classify_ip_key = self.total_calssify_key + ":" + classify_name

        # 2, 检查该 classify_ip_key 是否存在
        if not self.redis_cli.exists(classify_ip_key):
            self.logging.error(f"分类代理池 {classify_name} 不存在，请先配置好之后再获取代理！")
            self.set_status(404)
            self.write(json.dumps({'status': 'error', 'message': f'分类 {classify_name} 的代理池不存在'}))
            return

        # 3, 如果存在则按顺序依次获取一个IP，如果获取不到则等待间隔3s获取一次，最多尝试10次
        retries = 10
        interval = 3  # 间隔3秒
        ip_address = None

        for attempt in range(retries):
            ip_address = self.redis_cli.lpop(classify_ip_key)  # 从list头部获取IP
            if ip_address:
                break  # 成功获取到IP，跳出循环
            else:
                self.logging.info(f"第 {attempt + 1} 次尝试获取代理失败，等待 {interval} 秒后重试...")
                time.sleep(interval)  # 如果没有获取到，等待3秒

        if ip_address:
            self.logging.info(f"成功获取代理IP：{ip_address}")
            self.set_status(200)
            self.write(json.dumps({'status': 'success', 'ip': ip_address}))
        else:
            self.logging.error(f"尝试 {retries} 次后仍未获取到代理IP")
            self.set_status(500)
            self.write(json.dumps({'status': 'error', 'message': '获取代理IP失败，请稍后重试'}))
